home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / demos / 212 / gfa / boolean.doc next >
Encoding:
Text File  |  1988-01-13  |  23.9 KB  |  1,057 lines

  1.  
  2.  
  3.                                                                    -1-
  4.  
  5.  
  6.  
  7.  
  8.  
  9.                      BOOLEAN OPERATIONS IN BASIC LANGUAGE
  10.  
  11.  
  12.  
  13.            It was like digging skeletons out of the closet.  I knew
  14.  
  15.          that old college algebra book was somewhere, but we had just
  16.  
  17.          moved and all of the family's books were stored in no less
  18.  
  19.          than 24 sealed boxes.  Of course, after hours of digging, I
  20.  
  21.          found it...in the next to the last box.  For years I have
  22.  
  23.          used comparison and logical operations in my Basic programs
  24.  
  25.          without knowing the underlying theory; but if I was going to
  26.  
  27.          write an article to help beginner Basic programmers
  28.  
  29.          transition to intermediate programming, I'd better have a
  30.  
  31.          reference.  Finally on page 236, I found a brief section on
  32.  
  33.          Boolean algebra.
  34.  
  35.            In the simple world of Boole, everything is either black or
  36.  
  37.          white; that is, it is either TRUE or FALSE.  You can reduce a
  38.  
  39.          series of IF-THEN logical operations to a single line of code
  40.  
  41.          using Boolean algebra, thus adding speed to the program and
  42.  
  43.          reducing the length of the source code.  The examples in this
  44.  
  45.          tutorial are written in the popular GFA BASIC, my favorite
  46.  
  47.          language for the ST series, but the ideas on Boolean
  48.  
  49.          comparisons can be universally applied to any Basic language
  50.  
  51.          program.
  52.  
  53.  
  54.  
  55.                                 BOOLEAN BASICS
  56.  
  57.  
  58.  
  59.            Boolean algebra looks at a mathematical comparison and
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.                                                                    -2-
  70.  
  71.  
  72.  
  73.          determines if it is TRUE or FALSE, and then assigns a value
  74.  
  75.          to the result.  In GFA BASIC, TRUE = negative one(-1) and
  76.  
  77.          FALSE = zero(0).  You have to be careful because all Basic
  78.  
  79.          languages are not identical.  For example, in Atari-800
  80.  
  81.          Basic, TRUE = positive one(+1) and FALSE = zero(0).
  82.  
  83.            Let's begin with this mathematical comparison:
  84.  
  85.  
  86.  
  87.                    X=12
  88.  
  89.  
  90.  
  91.            As a simple mathematical comparison function, X is equated
  92.  
  93.          to twelve.  But in Boolean algebra, if X is equal to twelve,
  94.  
  95.          then the condition is TRUE and the statement is assigned the
  96.  
  97.          value of negative one; or if X is not equal to twelve, then
  98.  
  99.          the condition is FALSE and the statement is assigned the
  100.  
  101.          value of zero.  Putting this into Basic code, consider the
  102.  
  103.          brief program below:
  104.  
  105.  
  106.  
  107.                    Let X=5
  108.  
  109.                    Let Y=5
  110.  
  111.                    Z = (X=12) + (Y<10)
  112.  
  113.                    Print "Z equals ";Z
  114.  
  115.  
  116.  
  117.            As a beginner basic programmer, comparing a variable (Z) to
  118.  
  119.          other comparison statements (X=12, Y<10) combined with
  120.  
  121.          arithmetic functions (plus sign) made me scratch my head
  122.  
  123.          because the equation looked like nonsense; but this is a
  124.  
  125.          classic basic Boolean operation.  We know that X=5 and Y=5 by
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.                                                                    -3-
  136.  
  137.  
  138.  
  139.          previous initialization or calculation.  So what does Z equal
  140.  
  141.          by Boolean algebra?  X equals five, so (X=12) is FALSE and
  142.  
  143.          has a value of zero.  Y also equals five, so (Y<10) is TRUE
  144.  
  145.          and has a value of negative one.   Therefore, Z equals zero
  146.  
  147.          plus negative one for a total value of negative one.
  148.  
  149.            As demonstrated, you can utilize any of the comparison
  150.  
  151.          functions with Boolean algebra; equals (=), less than (<),
  152.  
  153.          greater than (>), not equal to (<>), greater than or equal to
  154.  
  155.          (>=), and less than or equal to (<=).
  156.  
  157.            If you haven't caught on to the potential power of Boolean
  158.  
  159.          operations yet, don't worry.  You'll find that the following
  160.  
  161.          program examples and descriptive text will give you concrete
  162.  
  163.          guidelines for the practical use of Boolean operations.
  164.  
  165.  
  166.  
  167.                    REPLACING CONDITIONAL IF-THEN STATEMENTS
  168.  
  169.  
  170.  
  171.            A common use of Boolean operations is to replace a series
  172.  
  173.          of related conditional IF-THEN statements with a streamlined
  174.  
  175.          Boolean statement.  If there are a large number of IF-THEN
  176.  
  177.          statements in the subroutine, then the savings in Basic
  178.  
  179.          source code space can be significant.
  180.  
  181.            The easiest example of this concept is when IF-THEN
  182.  
  183.          statements are used to elicit a TRUE or FALSE response, such
  184.  
  185.          as setting flags.  Study the following example and note how
  186.  
  187.          IF-THEN statements can be replaced by one line of Boolean
  188.  
  189.          code:
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.                                                                    -4-
  202.  
  203.  
  204.  
  205.                    Do
  206.  
  207.                      Print "Select 'Y' to turn flag TRUE"
  208.  
  209.                      Repeat
  210.  
  211.                        Z$=Inkey$
  212.  
  213.                      Until Z$<>""
  214.  
  215.                      If Z$="Y" Then
  216.  
  217.                        Flag=True
  218.  
  219.                      Endif
  220.  
  221.                      If Z$<>"Y" Then
  222.  
  223.                        Flag=False
  224.  
  225.                      Endif
  226.  
  227.                      Print "Flag value = ";Flag
  228.  
  229.                    Loop
  230.  
  231.  
  232.  
  233.            Using a Boolean operation, this program can be changed to:
  234.  
  235.  
  236.  
  237.                    Do
  238.  
  239.                      Print "Select 'Y' to turn Flag TRUE"
  240.  
  241.                      Repeat
  242.  
  243.                        Z$=Inkey$
  244.  
  245.                      Until Z$<>""
  246.  
  247.                      Flag=(Z$="Y")      !BOOLEAN OPERATION
  248.  
  249.                      Print "Flag value = ";Flag
  250.  
  251.                    Loop
  252.  
  253.  
  254.  
  255.            The REPEAT-UNTIL loop waits until you select a key.  If you
  256.  
  257.          select "Y", then Z$="Y" is TRUE and the value of the Flag is
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.                                                                    -5-
  268.  
  269.  
  270.  
  271.          set to negative one(-1).  If you select another letter, such
  272.  
  273.          as "N", then Z$="Y" is FALSE and the value of the Flag
  274.  
  275.          variable is set to zero(0).
  276.  
  277.            Okay, this is only a minor change in code; but let's
  278.  
  279.          consider a more lengthy comparison you might have embedded in
  280.  
  281.          a program:
  282.  
  283.  
  284.  
  285.                    If Z=10 Then
  286.  
  287.                      X=1
  288.  
  289.                    Endif
  290.  
  291.                    If Z=15 Then
  292.  
  293.                      X=2
  294.  
  295.                    Endif
  296.  
  297.                    If Z=20 Then
  298.  
  299.                      X=4
  300.  
  301.                    Endif
  302.  
  303.                    If Z=25 Then
  304.  
  305.                      X=8
  306.  
  307.                    Endif
  308.  
  309.  
  310.  
  311.            With Boolean operations to the rescue, this series of
  312.  
  313.          conditional IF-THEN's is reduced to:
  314.  
  315.  
  316.  
  317.                    X = ABS((Z=10) + 2*(Z=15) + 4*(Z=20) + 8*(Z=25))
  318.  
  319.  
  320.  
  321.            "Pretty compact now," I would say.  One disadvantage is
  322.  
  323.          that this Boolean contraction is visually distracting,
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.                                                                    -6-
  334.  
  335.  
  336.  
  337.          increasing the chances for hidden bugs, compared to the
  338.  
  339.          orderly layout of IF-THEN statements.  Fortunately, the GFA
  340.  
  341.          BASIC Editor won't let you get away with incorrect usage of
  342.  
  343.          mathematical symbols.  I usually write the program with the
  344.  
  345.          modular IF-THEN statements first.  If the program is running
  346.  
  347.          well, I will go back into the source code and apply Boolean
  348.  
  349.          operations where I can, testing the program after each
  350.  
  351.          change, before finally compiling the code.
  352.  
  353.            The calculation of this Boolean operation above would be as
  354.  
  355.          follows:
  356.  
  357.               If Z is not 10,15,20, or 25, then the expression would
  358.  
  359.          be: X equals the absolute value of (0+2*(0)+4*(0)+8*(0)), or
  360.  
  361.          X equals zero.
  362.  
  363.               If Z equals 10, then the expression would be: X equals
  364.  
  365.          the absolute value of ((-1)+2*(0)+4*(0)+8*(0)), or X equals
  366.  
  367.          one.
  368.  
  369.               If Z equals 15, then the expression would be: X equals
  370.  
  371.          the absolute value of (0+2*(-1)+4*(0)+8*(0)), or X equals
  372.  
  373.          two.
  374.  
  375.               If Z equals 20, then the expression would be: X equals
  376.  
  377.          the absolute value of (0+2*(0)+4*(-1)+8*(0)), or X equals
  378.  
  379.          four.
  380.  
  381.               If Z equals 25..., well, I'll let you derive this
  382.  
  383.          condition as a Boolean exercise, because you will be doing
  384.  
  385.          similar calculations in the following practical examples of
  386.  
  387.          an error trapping subroutine and a menu click detection
  388.  
  389.          subroutine.
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.                                                                    -7-
  400.  
  401.  
  402.  
  403.  
  404.  
  405.                            ERROR TRAPPING SUBROUTINE
  406.  
  407.  
  408.  
  409.            Study the "***ERROR TRAPPING SUBROUTINE ***" below written
  410.  
  411.          in GFA BASIC.  The subroutine catches errors as they occur in
  412.  
  413.          the main program and converts some of the more commonly
  414.  
  415.          occuring error numbers into English text in an Alert Box.
  416.  
  417.          Since the error numbers that I selected for the conversion to
  418.  
  419.          English are random, irregular positive and negative numbers,
  420.  
  421.          I could not quickly dream up an algebraic routine to point to
  422.  
  423.          the English error message by an offset value.  I'm not a
  424.  
  425.          mathematical genius!  So, normally the Basic programmer would
  426.  
  427.          develop a series of conditional IF-THEN statements to handle
  428.  
  429.          the conversion of an error number to English.  A few of these
  430.  
  431.          IF-THEN statements might be as follows:
  432.  
  433.  
  434.  
  435.                    If En%=22 Then
  436.  
  437.                      Error_message$="FILE ALREADY OPEN"
  438.  
  439.                    Endif
  440.  
  441.                    If En%=24 Then
  442.  
  443.                      Error_message$="FILE NOT OPENED"
  444.  
  445.                    Endif
  446.  
  447.                    ' !...ONE STATEMENT FOR EACH ERROR NUMBER...
  448.  
  449.                    If En%=(-39) Then
  450.  
  451.                      Error_message$="MEMORY FULL"
  452.  
  453.                    Endif
  454.  
  455.                    ' !...AND SO ON...
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.                                                                    -8-
  466.  
  467.  
  468.  
  469.  
  470.  
  471.             Sixteen IF-THEN statements were removed by applying
  472.  
  473.          Boolean logic to the subroutine.  It is funny how things
  474.  
  475.          happen, but after I wrote this routine for my GFA BASIC
  476.  
  477.          programs, I discovered that "OPTION E+" in the GFA BASIC
  478.  
  479.          COMPILER inserts a subroutine into compiled GFA BASIC
  480.  
  481.          programs that converts error number messages into English
  482.  
  483.          text!
  484.  
  485.  
  486.  
  487.          ' *** ERROR TRAPPPING SUBROUTINE ***
  488.  
  489.          Procedure Er_trap
  490.  
  491.            Close    !CLOSE EVERYTHING
  492.  
  493.            En%=Err  !Err RETURNS ERROR NUMBER TO INTEGER VARIABLE En%
  494.  
  495.          '!BOOLEAN OPERATION REPLACES SIXTEEN IF-THEN STATEMENTS
  496.  
  497.          '!Er_dif% VARIABLE IS OFFSET TO ERROR NAME IN DATA SET BELOW
  498.  
  499.            Er_pnt% = Abs((En%=22)+2*(En%=24)+3*(En%=37)+4*(En%=50))
  500.  
  501.            Add Er_pnt%,Abs(5*(En%=48)+6*(En%=51)+7*(En%=52))
  502.  
  503.            Add Er_pnt%,Abs(8*(En%=53)+9*(En%=54)+10*(En%=55))
  504.  
  505.            Add Er_pnt%,Abs(11*(En%=-10)+12*(En%=-11)+13*(En%=-13))
  506.  
  507.            Add Er_pnt%,Abs(14*(En%=-33)+15*(En%=-34)+16*(En%=-39))
  508.  
  509.            If Er_pnt%=0 !IF ERROR NOT COMMON Err#, PRINT THE NUMBER
  510.  
  511.              Error_message$="ERROR # "+Str$(En%)+" OCCURRED"
  512.  
  513.              Alert 1,Error_message$,1,"CONT",B%
  514.  
  515.            Else
  516.  
  517.              Restore Er_data      !IF ERROR IS COMMON Err NUMBER,
  518.  
  519.              For I%=1 To Er_pnt%  !FIND ENGLISH TEXT IN DATA SET
  520.  
  521.                Read Error_message$
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.                                                                    -9-
  532.  
  533.  
  534.  
  535.              Next I%              !AND SEND TEXT TO THE ALERT BOX
  536.  
  537.              Alert 1,Error_message$,1,"CONT",B%
  538.  
  539.            Endif
  540.  
  541.            On Error Gosub Er_trap !RESET ERROR HANDLER
  542.  
  543.            Clr En%             !CLEAR ERROR NUMBER VARIABLE
  544.  
  545.            Resume Begin_again  !RESTART FILESELECT PROC. IN MAIN PRG
  546.  
  547.            Er_data:            !DATA SET OF COMMON ERRORS
  548.  
  549.            Data "FILE ALREADY OPENED","FILE NOT OPENED"
  550.  
  551.            Data "DISKETTE FULL","NOT AN 'R' FILE"
  552.  
  553.            Data "OPEN 'R' FILE | RECORD LENGTH WRONG"
  554.  
  555.            Data "ONLY ONE FIELD PER | OPEN 'R' ALLOWED"
  556.  
  557.            Data "FIELDS LARGER THAN |   RECORD LENGTH"
  558.  
  559.            Data "TOO MANY FIELDS (MAX=9)"
  560.  
  561.            Data "GET/PUT FIELDS | STRING LENGTH WRONG"
  562.  
  563.            Data "GET/PUT RECORD | NUMBER WRONG ","WRITE FAULT"
  564.  
  565.            Data "READ FAULT","DISKETTE WRITE PROTECTED"
  566.  
  567.            Data "FILE NOT FOUND","PATH NOT FOUND","MEMORY FULL"
  568.  
  569.          Return
  570.  
  571.  
  572.  
  573.            To demonstrate how the Boolean operation works in this
  574.  
  575.          error trapping subroutine, let's presume that you are
  576.  
  577.          utilizing a FILESELECT subroutine in your program to send a
  578.  
  579.          data array, such as a series of names and addresses, from RAM
  580.  
  581.          to a sequential disk file.  You've selected the filename, and
  582.  
  583.          clicked "Enter"; but your diskette cannot receive the data
  584.  
  585.          since the Write-Protection Tab is in the "write-protect-on"
  586.  
  587.          position.  This will generate an error number that is trapped
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.                                                                    -10-
  598.  
  599.  
  600.  
  601.          by the error trapping subroutine.  The GFA BASIC manual, page
  602.  
  603.          240 (version 2.0), notes that such an error will generate a
  604.  
  605.          TOS error number of (-13).  Therefore, the only TRUE
  606.  
  607.          comparison in the Boolean operation above is (En%=-13).  So
  608.  
  609.          the absolute value of 13*(En%=-13) equals ABS(13*(-1)), or
  610.  
  611.          thirteen.  All of the other comparisons are FALSE, resulting
  612.  
  613.          in zeros for the rest of the Boolean equation.  Therefore,
  614.  
  615.          adding up all of the results of these Boolean comparisons
  616.  
  617.          gives the variable, Er_pnt%, a value of 13.  The READ-DATA
  618.  
  619.          subroutine will then put the thirteenth English text error
  620.  
  621.          message into the Alert Box.
  622.  
  623.            If the error number had been (51), then the sixth English
  624.  
  625.          text error message would have been put into the Alert Box.
  626.  
  627.            I hope by now you are catching onto the idea of using
  628.  
  629.          Boolean operations.
  630.  
  631.  
  632.  
  633.                              HANDLING MENU CLICKS
  634.  
  635.  
  636.  
  637.            Every GFA BASIC program that uses pull-down menus is
  638.  
  639.          accompanied by a subroutine to conditionally read the "click"
  640.  
  641.          on a menu item, referring the program to another subroutine.
  642.  
  643.          When studying the source code with the GFA BASIC EDITOR, you
  644.  
  645.          will usually see several screenfuls of menu click conditional
  646.  
  647.          IF-THEN statements, such as:
  648.  
  649.  
  650.  
  651.                    If Menu(0)=20 Then
  652.  
  653.                      Gosub Procedure_three
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.                                                                    -11-
  664.  
  665.  
  666.  
  667.                    Endif
  668.  
  669.                    ' !... AND SO ON ...
  670.  
  671.  
  672.  
  673.            A whole series of IF-THEN statements can be changed to a
  674.  
  675.          line or two of "ON-(integer variable)-GOSUB-(routine)"
  676.  
  677.          statements using Boolean comparisons.  Study the " *** MENU
  678.  
  679.          CLICK DETECTION SUBROUTINE ***" below:
  680.  
  681.  
  682.  
  683.          ' *** MENU CLICK DETECTION SUBROUTINE ***
  684.  
  685.          Procedure Menclick
  686.  
  687.            Q%=Menu(0)  !VARIABLE, Q%, HOLDS # OF MENU ITEM CLICKED
  688.  
  689.            ' REPLACE TWELVE IF-ENDIF's WITH BOOLEAN OPERATION
  690.  
  691.            Z%=Abs(1*(Q%=15)+2*(Q%=16)+3*(Q%=18)+4*(Q%=21)
  692.  
  693.                  +5*(Q%=22)+6*(Q%=23)+7*(Q%=26)+8*(Q%=27)
  694.  
  695.                  +9*(Q%=28)+10*(Q%=29)+11*(Q%=32))+12*(Q%=34))
  696.  
  697.            On Z% Gosub Loadfont,Savefont,Quitprog,Printerreset,
  698.  
  699.                        Dlfont,Testfont,Createchar,Editchar,
  700.  
  701.                        Copychar,Deletechar,Restorechar,Asciibox
  702.  
  703.          Return
  704.  
  705.  
  706.  
  707.            Now that you are getting more in tune with the Boolean way
  708.  
  709.          of thinking, I'll just give a quick example for the routine
  710.  
  711.          above.  Suppose that you clicked the menu item
  712.  
  713.          "Printerreset".  The integer variable, Z%, would equal the
  714.  
  715.          absolute value of (1*(0)+2*(0)+3*(0)+4*(-1)+5*(0)...+12*(0)),
  716.  
  717.          or four.  The next line of code states, "On four, gosub
  718.  
  719.          Printerreset."
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.                                                                    -12-
  730.  
  731.  
  732.  
  733.  
  734.  
  735.                    READING JOYSTICKS AND CHECKING BOUNDARIES
  736.  
  737.  
  738.  
  739.            For this final example, you will find it helpful to refer
  740.  
  741.          to figure 1., which shows all of the ST-joystick position
  742.  
  743.          values.  When the joystick is centered, a value of zero is
  744.  
  745.          returned.  When the joystick is moved to the upper-right
  746.  
  747.          position, a value of nine is returned.
  748.  
  749.            Let's say you wanted to move a Sprite about the screen, but
  750.  
  751.          wanted to keep it inside a box.  The X,Y coordinates of the
  752.  
  753.          upper-left corner of the box are 50,50; and the X,Y
  754.  
  755.          coordinates of the lower-right corner of the box are
  756.  
  757.          500,150.
  758.  
  759.            The joystick is read to determine which way the Sprite
  760.  
  761.          should move.  To move the Sprite, you will be incrementing X
  762.  
  763.          by one for any joystick inputs to the right and you will be
  764.  
  765.          incrementing Y by one for any joystick inputs downward.
  766.  
  767.          Decrementing the X and Y values with joystick inputs will
  768.  
  769.          move the Sprite in the corresponding opposite directions.
  770.  
  771.            To read the joystick, you would have to set up eight
  772.  
  773.          conditional IF-THEN statements, such as:
  774.  
  775.  
  776.  
  777.                    If Joystick%=10 Then
  778.  
  779.                      X=X+1    !MOVE THE SPRITE DOWN AND RIGHT
  780.  
  781.                      Y=Y+1
  782.  
  783.                    Endif
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.                                                                    -13-
  796.  
  797.  
  798.  
  799.            To check the boundaries, you would have to set up four
  800.  
  801.          conditional IF-THEN statements, such as:
  802.  
  803.  
  804.  
  805.                    If X>500  Then
  806.  
  807.                      X=500    !KEEP 'X' INSIDE RIGHT BORDER
  808.  
  809.                    Endif
  810.  
  811.  
  812.  
  813.            That adds about forty lines of IF-THEN-ENDIF statements to
  814.  
  815.          your source code.  Study the next example of Boolean logic
  816.  
  817.          and follow the explanation of how it works.  This subroutine
  818.  
  819.          is integrated into the brief GFA BASIC program listing
  820.  
  821.          accompanying this tutorial, so you can have fun moving the
  822.  
  823.          Sprite around "The Sprite Corral."
  824.  
  825.  
  826.  
  827.            If S%>0    ! JOYSTICK MOVED FROM CENTER POSTION
  828.  
  829.              '!TESTS FOR 8 JOYSTICK POSITIONS AND CHECKS BOUNDARIES
  830.  
  831.              '!BOOLEAN COMPARISONS REPLACE 12 IF-THEN STATEMENTS
  832.  
  833.              Add X%,(S%>7 And S%<11)*(X%<500)-(S%>3 And S%<7)*(X%>50)
  834.  
  835.              Add Y%,(S% Mod 4=2)*(Y%<150)-(S% Mod 4=1)*(Y%>50)
  836.  
  837.            Endif
  838.  
  839.            Sprite S$,X%,Y%   ! POSITIONS SPRITE
  840.  
  841.  
  842.  
  843.            All joystick inputs to the right return the values of 9, 8,
  844.  
  845.          or 10; that is: (S%>7 And S%<11).  All joystick inputs to the
  846.  
  847.          left return values that are: (S%>3 And S%<7).  All joystick
  848.  
  849.          inputs upward return the values of 5,1, or 9, which are
  850.  
  851.          divisible by four with a remainder of one; that is: (S% Mod
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.                                                                    -14-
  862.  
  863.  
  864.  
  865.          4=1).  All joystick inputs downward return values that are
  866.  
  867.          divisible by four with a remainder of 2: (S% Mod 4=2).  These
  868.  
  869.          four comparisons are unique to each of the four cardinal
  870.  
  871.          directions of joystick input.
  872.  
  873.            Let's do the Boolean calculations for a given situation.
  874.  
  875.          The Sprite is at X,Y coordinates of 100,125.  You move the
  876.  
  877.          joystick to the right, returning a value of S%=8.  The
  878.  
  879.          comparisons (S%>7 And S%<11), (X%<500), (X%>50), (Y%<150),
  880.  
  881.          and (Y%>50) are TRUE and are assigned the value of (-1).  All
  882.  
  883.          other Boolean comparisons are FALSE and are assigned the
  884.  
  885.          value of (0).  The calculation is then:
  886.  
  887.                    Add X%,(-1*-1) - (0*-1) or Add X%,1
  888.  
  889.                    Add Y%,(0*-1) - (0*-1)  or Add Y%,0
  890.  
  891.            This moves the Sprite to the right by one with new X,Y
  892.  
  893.          coordinates of 101,125.
  894.  
  895.            To show how boundaries are checked, keep pushing the Sprite
  896.  
  897.          to the right until the X coordinate is 500.  Stop.  Now try
  898.  
  899.          to move the Sprite to the right, returning a joystick
  900.  
  901.          position value of S%=8.  Again the comparisons (S%>7 And
  902.  
  903.          S%<11), (X%>50), (Y%<150), and (Y%>50) are TRUE and are
  904.  
  905.          assigned a value of (-1).  But now the comparison (X%<500) is
  906.  
  907.          FALSE and is assigned a value of (0).  The other comparisons
  908.  
  909.          remain FALSE.  The calculation is now:
  910.  
  911.                    Add X%,(-1*0) - (0*-1) or Add X%,0
  912.  
  913.                    Add Y%,(0*-1) - (0*-1) or Add Y%,0
  914.  
  915.            The Sprite will not move past the right X boundary of 500
  916.  
  917.          despite your joystick input to the right.
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927.                                                                    -15-
  928.  
  929.  
  930.  
  931.            A more complicated and final situation might find the
  932.  
  933.          Sprite at X,Y coordinates of 100,150.  You push the joystick
  934.  
  935.          downward and to the left, returning a joystick position value
  936.  
  937.          of S%=6.  The comparisons (S% Mod 4=2), (S%>3 And S%<7),
  938.  
  939.          (X%>50), (X%<500), and (Y%>50) are TRUE and are assigned a
  940.  
  941.          value of (-1).  The other comparisons are FALSE and are
  942.  
  943.          assigned a value of (0).  The Boolean calculations are:
  944.  
  945.                    Add X%,(0*-1) - (-1*-1) or Add X%,(-1)
  946.  
  947.                    Add Y%,(-1*0) - (0*-1)  or Add Y%,0
  948.  
  949.            The Sprite moves to the left, but is unable to move below
  950.  
  951.          the lower Y boundary of 150.  The new Sprite X,Y coordinates
  952.  
  953.          are 99,150.
  954.  
  955.            With the assistance of this tutorial, the beginner GFA
  956.  
  957.          BASIC programmer should have a better understanding of
  958.  
  959.          Boolean operations and will be able to employ them in future
  960.  
  961.          programming efforts to reduce the object code length and
  962.  
  963.          improve the speed of program execution.  Of course, Boolean
  964.  
  965.          algebra is an unusual way of calculating equations, so don't
  966.  
  967.          feel overwhelmed if you have to read this tutorial over
  968.  
  969.          again.  I had to read that section in my algebra book three
  970.  
  971.          times.
  972.  
  973.  
  974.  
  975.                                GFA BASIC LISTING
  976.  
  977.  
  978.  
  979.          ' *** MOVE SPRITE WITH JOYSTICK IN PORT 1 ***
  980.  
  981.          Sp$=Mki$(1)+Mki$(1)+Mki$(0)+Mki$(0)+Mki$(1) ! DEFINE SPRITE
  982.  
  983.          For I%=1 To 16
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.                                                                    -16-
  994.  
  995.  
  996.  
  997.            Sp$=Sp$+Mki$(0)+Mki$(65535)
  998.  
  999.          Next I%
  1000.  
  1001.          Deffill 3,2,6   !DRAW THE BOX TO HOLD THE SPRITE
  1002.  
  1003.          Pbox 50,49,514,164
  1004.  
  1005.          Print At(30,14);Chr$(27);"c2";"The Sprite Corral";
  1006.  
  1007.          X%=50           !PUT SPRITE IN BOX
  1008.  
  1009.          Y%=50
  1010.  
  1011.          Print At(1,24);"Press any key to quit";
  1012.  
  1013.          Hidem
  1014.  
  1015.          '
  1016.  
  1017.          Repeat    !Peek $FFFC02 = QUICK READ JOYSTICK POSITION
  1018.  
  1019.            @Readjoy(Peek(&HFFFC02))
  1020.  
  1021.          Until Inkey$<>"" !PRESS ANY KEY TO QUIT GFA BASIC ROUTINE
  1022.  
  1023.          Out 4,&H8        ! TURN MOUSE BACK ON WHEN EXIT PROGRAM
  1024.  
  1025.          '
  1026.  
  1027.          Procedure Readjoy(S%)!PASS VALUE Peek $FFFC02 TO VARIABLE S%
  1028.  
  1029.            If S%>0            ! JOYSTICK MOVED FROM CENTER POSTION
  1030.  
  1031.              ' TESTS FOR 8 JOYSTICK POSITIONS AND CHECKS BOUNDARIES
  1032.  
  1033.              ' !REPLACES 12 IF-THEN STATEMENTS
  1034.  
  1035.              Add X%,(S%>7 And S%<11)*(X%<500)-(S%>3 And S%<7)*(X%>50)
  1036.  
  1037.              Add Y%,(S% Mod 4=2)*(Y%<150)-(S% Mod 4=1)*(Y%>50)
  1038.  
  1039.            Endif
  1040.  
  1041.            Vsync             ! REMOVES ANIMATION FLICKER
  1042.  
  1043.            Sprite S$,X%,Y%   ! POSITIONS SPRITE
  1044.  
  1045.          Return
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.